---
title: Distribute a document
summary: Distributes a document via an MSMQ queue or a direct xPression call, covering print, imaging, e-mail, fax, and deferred output.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-09-01
library: SAIF.Services.Printing
reference_type: embedded
operation_id: op-04-distribute-a-document
trigger: clsPrint.distributeDocument invoked
---

# Distribute a document

Distributes a document either by queuing a composite print request through MSMQ or by calling the xPression service directly, depending on the `Asynchronous` setting, covering print, imaging, e-mail, fax, and deferred output channels in a single request.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-04 |
| **Trigger** | `clsPrint.distributeDocument` invoked |
| **Inputs** | Package, XML, plus instance state `Printer`, `PlexMode`, `Copies`, `ScaleMode`, `Format`, `OutputProfile`, `ImportInfo`, `EmailInfo`, `FaxInfo`, `DeferredInfo`, `IDMPath` (derived from environment configuration) |
| **Outputs** | `True`; side effect is an MSMQ message send or a direct SOAP call |
| **Primary components** | `clsPrint.distributeDocument` (public), private `distributeDocument()`, `CompositeRequestClass`, `StartMQTransaction`/`EndMQTransaction`, `m_Xpresso.distributeDocument` |
| **Entry point** | `SAIF.Services.Printing/clsPrint.vb` |

## Steps

1. Trims and assigns `inPackage` to the `Package` property. The package name is normalized by stripping a trailing `.pkg` extension via the `Package` setter ([BR-PRT-001](../business-rules.md#br-prt-001-package-name-extension-normalization)).
2. Assigns `inXML` to the `XML` property.
3. Delegates to the private parameterless `distributeDocument()`, which branches on the `Asynchronous` property ([BR-PRT-003](../business-rules.md#br-prt-003-synchronous-versus-queued-distribution)).
4. **Asynchronous branch:**
   - Lazily creates `m_Queue` from `m_MessagePath` (a config-driven MSMQ path) if it is not already open.
   - Builds a `CompositeRequestClass` snapshotting `Package`, `XML`, `Printer`, `PlexMode`, `Copies`, `ScaleMode`, `Format`, `OutputProfile`, `ImportInfo` (the raw object, not its serialized string form), `EmailInfo`, `FaxInfo`, `IDMPath`, and `DeferredInfo`.
     - The `CompositeRequestClass.Tray` field is left at its default value in this branch — it is never assigned, unlike the synchronous branch's fixed `PaperTray.Tray2`.*
   - Wraps the snapshot in a `Message` using `Messaging.BinaryMessageFormatter`.
   - If the caller already started a transaction, sends the message on that existing transaction; otherwise starts a new transaction, sends the message, and commits it for just this one message ([BR-PRT-004](../business-rules.md#br-prt-004-transactional-msmq-send)).

     > **Origin:** The transaction start/commit mechanic used here is the same logic documented in [MSMQ transaction management](op-05-msmq-transaction-management.md) (`StartMQTransaction`/`EndMQTransaction`); see that page for the full behavior rather than a re-description here.
   - On failure: rolls back the transaction (`EndMQTransaction(False)`) and rethrows the exception ([BR-PRT-005](../business-rules.md#br-prt-005-msmq-failure-rollback)).
5. **Synchronous branch:** calls `m_Xpresso.distributeDocument(m_Package, m_XML, m_Printer, m_Plexmode, m_Copies, m_Scalemode, m_OutputProfile, ImportInfoString, m_EmailInfo, m_FaxInfo, IDMPath, PaperTray.Tray2, m_DeferredInfo, m_Application)` directly against the xPression SOAP service, hard-coding `PaperTray.Tray2` regardless of any caller preference ([BR-PRT-006](../business-rules.md#br-prt-006-fixed-paper-tray-for-synchronous-distribution)).
   - This branch passes `ImportInfoString` (the serialized string form of `ImportInfo`) to the SOAP call, whereas the asynchronous branch's `CompositeRequestClass` snapshot instead carries the raw `ImportInfo` object — a structural asymmetry between the two branches.*
6. Returns `True` unconditionally, both on the synchronous path and after a successful asynchronous send ([BR-PRT-013](../business-rules.md#br-prt-013-print-and-distribute-report-unconditional-success)).

## Process flow

```mermaid
flowchart TD
	Start(["distributeDocument invoked"]) --> Norm["Normalize package name"]
	Norm --> Decision{"Asynchronous?"}
	Decision -->|Yes| Tx["Start/reuse MSMQ transaction"]
	Tx --> Build["Build CompositeRequestClass<br>(Tray left unset)"]
	Build --> Send["Send via BinaryMessageFormatter"]
	Send --> Commit["Commit transaction"]
	Commit --> EndYes(["Return True"])
	Tx -->|Exception| Rollback["Rollback and rethrow"]
	Decision -->|No| Direct["Direct xPression distributeDocument<br>Tray2 fixed"]
	Direct --> EndNo(["Return True"])
```

## Failure and edge-case behavior
- Asynchronous failures roll back the MSMQ transaction and rethrow — no partially-sent message survives ([BR-PRT-005](../business-rules.md#br-prt-005-msmq-failure-rollback)).
- The synchronous branch has no equivalent rollback mechanism, since no transaction exists on that path.
- The synchronous branch's `True` return happens even though the underlying SOAP call could itself throw before returning — the same [BR-PRT-013](../business-rules.md#br-prt-013-print-and-distribute-report-unconditional-success) caveat described in [Print rendered bytes](op-03-print-rendered-bytes.md) applies here.
- The `CompositeRequestClass.Tray` field is never set in the asynchronous branch, so a queued message's tray value is whatever the default `PaperTray` enum value is, unlike the synchronous branch's explicit `Tray2` — a discrepancy between the two distribution paths that is not currently reconciled by a business rule.*

## Related documentation
- [Index](../index.md)
- [Overview](../overview.md)
- [Architecture](../architecture.md)
- [Dependencies](../dependencies.md)
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Configuration](../configuration.md)
- [API reference](../api/index.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Services.Printing/clsPrint.vb`
